package com.aia.prm.web.ria.app;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jxls.transformer.XLSTransformer;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.aia.prm.web.ria.app.ui.G2View;
import com.aia.prm.web.ria.app.ui.qnae.QnaeView;
import com.aia.prm.web.ria.app.ui.qnbe.QnbeView;
import com.aia.prm.web.ria.app.ui.qnce.QnceView;
import com.aia.prm.web.ria.app.ui.qnde.QndeView;
import com.aia.prm.web.ria.app.ui.qne.QneView;
import com.aia.prm.web.ria.app.ui.qnfe.QnfeView;
import com.cfh.util.Tools;
import com.vaadin.terminal.DownloadStream;
import com.vaadin.terminal.URIHandler;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Window;

@SuppressWarnings({ "serial", "unchecked", "rawtypes" })
public class MyURIHandlerForQne implements URIHandler, Serializable {
	private static final Logger logger = Logger.getLogger(MyURIHandlerForQne.class);
	PrmApplication app;
	private final static String EXCEL_MIME = "application/vnd.ms-excel";

	MyURIHandlerForQne(PrmApplication arg) {
		app = arg;
	}

	private G2View fetchG2View() {
		try {
			return (G2View) app.getMainWindow().getContent();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}

	private QneView fetchQneView() {
		try {
			return (QneView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}

	public DownloadStream handleURI(URL context, String relativeUri) {
		if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQne")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QneView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQneView().fetchReportList();
				return buildQneReport(list, "/excel/prmQne.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		}

		else if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQnae")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QnaeView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQnaeView().fetchReportList();
				return buildQneReport(list, "/excel/prmQnae.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		} else if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQnbe")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QnbeView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQnbeView().fetchReportList();
				return buildQneReport(list, "/excel/prmQnbe.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		}  else if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQnce")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QnceView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQnceView().fetchReportList();
				return buildQneReport(list, "/excel/prmQnce.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		}else if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQnde")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QndeView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQndeView().fetchReportList();
				return buildQneReport(list, "/excel/prmQnde.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		}else if (Tools.hasText(relativeUri) && relativeUri.startsWith("reportQnfe")) {
			logger.debug("handleURI=" + relativeUri);
			try {
				validateQne(QnfeView.class);
			} catch (RuntimeException e) {
				return buildErrorReport(e.getMessage());
			}

			try {
				List list = fetchQnfeView().fetchReportList();
				return buildQneReport(list, "/excel/prmQnfe.xls");
			} catch (Exception e) {
				logger.error(e);
				return buildErrorReport(e.getMessage());
			}

		}

		return null;
	}

	private QnbeView fetchQnbeView() {
		try {
			return (QnbeView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}
	
	private QndeView fetchQndeView() {
		try {
			return (QndeView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}
	private QnfeView fetchQnfeView() {
		try {
			return (QnfeView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}
	private QnceView fetchQnceView() {
		try {
			return (QnceView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}

	private QnaeView fetchQnaeView() {
		try {
			return (QnaeView) fetchG2View().fetchSelectView();
		} catch (Exception e) {
			logger.warn("Should not error at fetchG2View:" + e, e);
			return null;
		}
	}

	private DownloadStream buildQneReport(List list, String excelPath) {
		Map<String, Object> beans = new HashMap<String, Object>();
		beans.put("list", list);
		beans.put("PRINT_DATE", Tools.dateToString(new java.util.Date(), "yyyy-MM-dd HH:mm:ss"));
		try {
			XLSTransformer transformer = new XLSTransformer();
			InputStream in = this.getClass().getResourceAsStream(excelPath);
			HSSFWorkbook workbook = transformer.transformXLS(in, beans);
			ByteArrayOutputStream imagebuffer = new ByteArrayOutputStream();
			workbook.write(imagebuffer);

			ByteArrayInputStream istream = new ByteArrayInputStream(imagebuffer.toByteArray());
			return new DownloadStream(istream, EXCEL_MIME, "Report_" + Tools.dateToString(new java.util.Date(), "yyyy-MM-dd_HH-mm-ss")
					+ ".xls");
		} catch (IOException e) {
			logger.error("report error:" + e);
			throw new RuntimeException(e);
		}
	}

	private void validateQne(Class clazz) throws RuntimeException {
		Object user = app.getUser();
		if (user == null) {
			logger.debug("user==null");
			throw new RuntimeException("您没有登录，或者会话超时");
		} else {
			logger.debug("user!=null");
		}

		Window currentWindow = app.getMainWindow();
		if (currentWindow == null) {
			logger.debug("currentWindow==null");
			throw new RuntimeException("出错，窗口为空");
		}
		ComponentContainer con = currentWindow.getContent();
		G2View g2view = null;
		if (con instanceof G2View) {
			g2view = (G2View) con;
		} else {
			throw new RuntimeException("您没有登录，请输入用户名与密码");
		}
		Component con2 = g2view.fetchSelectView();
		if (clazz.isAssignableFrom(con2.getClass())) {
		} else {
			throw new RuntimeException("错误的当前页面");
		}

	}

	private DownloadStream buildErrorReport(String string) {
		Map<String, Object> beans = new HashMap<String, Object>();
		beans.put("MESSAGE", string);
		try {
			XLSTransformer transformer = new XLSTransformer();
			InputStream in = this.getClass().getResourceAsStream("/excel/error.xls");
			HSSFWorkbook workbook = transformer.transformXLS(in, beans);
			ByteArrayOutputStream imagebuffer = new ByteArrayOutputStream();
			workbook.write(imagebuffer);

			ByteArrayInputStream istream = new ByteArrayInputStream(imagebuffer.toByteArray());
			return new DownloadStream(istream, EXCEL_MIME, "Error_" + Tools.getDateTime() + ".xls");
		} catch (IOException e) {
			logger.error("report error:" + e);
			throw new RuntimeException(e);
		}
	}

}
